package com.lp.zyll.security;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lp.zyll.constant.LpConstant;
import com.lp.zyll.domain.Role;
import com.lp.zyll.domain.User;
import com.lp.zyll.exception.BadRequestException;
import com.lp.zyll.redis.RedisCRUD;
import com.lp.zyll.service.RoleService;
import com.lp.zyll.service.UserService;
import com.lp.zyll.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class UserDetailsServiceImpl implements UserDetailsService {


    @Autowired
    UserService userService;

    @Autowired
    RoleService roleService;



    @Autowired
    RedisCRUD redisCRUD;

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {


        User user = userService.getOne(new QueryWrapper<User>().eq("username", account));

        if (user == null) {
            throw new BadRequestException("用户不存在");
        }
        return createLoginUser(user);
    }

    private UserDetails createLoginUser(User user) {

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        LoginUser loginUser = new LoginUser(user);
        String ip = StringUtils.getIp(request);
        String cityInfo = StringUtils.getCityInfo(ip);
        loginUser.setLoginLocation(cityInfo);
        loginUser.setIpaddr(ip);
        UUID uuid = UUID.randomUUID();
        loginUser.setToken(uuid.toString().replace("-",""));
        LocalDateTime now = LocalDateTime.now();
        loginUser.setLoginTime(now);
        loginUser.setExpireTime(now.plusDays(30));


        Role role = roleService.getById(user.getRoleId());
        String[] split = role.getRoleKey().split(",");
        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        for (String str:split
             ) {
            grantedAuthorities.add(new SimpleGrantedAuthority(str));
        }
        //
        String token = redisCRUD.get(LpConstant.TOKEN_KEY + user.getUsername());
        if (StringUtils.isNotEmpty(token)){
            redisCRUD.delete(LpConstant.TOKEN_PREFIX +token);
        }


        redisCRUD.set(LpConstant.TOKEN_KEY + user.getUsername(),loginUser.getToken());
        loginUser.setAuthorities(grantedAuthorities);
        redisCRUD.setObject(LpConstant.TOKEN_PREFIX +loginUser.getToken(),loginUser,LpConstant.tokenTime);
        return loginUser;
    }


}
